home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / Text.C < prev    next >
C/C++ Source or Header  |  1992-08-26  |  11KB  |  599 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "Text.h"
  6.  
  7. #include "Class.h"
  8. #include "Error.h"
  9. #include "RegularExp.h"
  10. #include "Mark.h"
  11. #include "Port.h"
  12. #include "OrdColl.h"
  13. #include "Math.h"
  14.  
  15. //---- formating properties ----------------------------------------------------
  16.  
  17. byte TextCharMap[] = {
  18. cTextBreak|cTextPara,         /* 0x00 */
  19. 0,                            /* 0x01 */
  20. 0,                            /* 0x02 */
  21. 0,                            /* 0x03 */
  22. 0,                            /* 0x04 */
  23. 0,                            /* 0x05 */
  24. 0,                            /* 0x06 */
  25. 0,                            /* 0x07 */
  26. 0,                            /* 0x08 */
  27. 0,                            /* 0x09 */
  28. cTextBreak|cTextPara,         /* 0x0a */
  29. 0,                            /* 0x0b */
  30. cTextBreak,                   /* 0x0c */
  31. cTextBreak,                   /* 0x0d */
  32. 0,                            /* 0x0e */
  33. 0,                            /* 0x0f */
  34. 0,                            /* 0x10 */
  35. 0,                            /* 0x11 */
  36. 0,                            /* 0x12 */
  37. 0,                            /* 0x13 */
  38. 0,                            /* 0x14 */
  39. 0,                            /* 0x15 */
  40. 0,                            /* 0x16 */
  41. 0,                            /* 0x17 */
  42. 0,                            /* 0x18 */
  43. 0,                            /* 0x19 */
  44. 0,                            /* 0x1a */
  45. 0,                            /* 0x1b */
  46. 0,                            /* 0x1c */
  47. 0,                            /* 0x1d */
  48. 0,                            /* 0x1e */
  49. 0,                            /* 0x1f */
  50. };
  51.  
  52. static TextChanges changeRec;
  53.  
  54. //---- VisualMark -----------------------------------------------------
  55.  
  56. NewMetaImpl0(VisualMark,Mark);
  57.  
  58. VisualMark::VisualMark() : Mark(0, 0, eStateNone, eMarkFixedSize)
  59.  
  60. {
  61. }
  62.     
  63. void VisualMark::CalcExtent()
  64. {
  65. }
  66.  
  67. int VisualMark::Base()
  68. {
  69.     return GetExtent().y;
  70. }
  71.  
  72. Point VisualMark::GetExtent()
  73. {
  74.     return gPoint0;
  75. }
  76.     
  77. void VisualMark::Draw(Point, Rectangle, Rectangle, bool)
  78. {
  79. }
  80.  
  81. void VisualMark::SendDown(int, int, void *)
  82. {
  83. }
  84.  
  85. void VisualMark::SetContainer(class VObject *)
  86. {
  87. }
  88.  
  89. bool VisualMark::WantsInput(Point)
  90. {
  91.     return FALSE;
  92. }
  93.  
  94. class Command *VisualMark::Input(Point, Token&, class Clipper *)
  95. {
  96.     return 0;
  97. }
  98.  
  99. class VObject *VisualMark::GetVObject()
  100. {
  101.     return 0;
  102. }
  103.  
  104. //---- Text ------------------------------------------------------------
  105.  
  106. NewAbstractMetaImpl(Text,Object, (TP(marks), TP(observers), T(tabWidth)));
  107.  
  108. Text::Text()
  109.     Init();
  110. }
  111.  
  112. Text::~Text()
  113. {   
  114.     if (marks) {
  115.     marks->FreeAll();
  116.     SafeDelete(marks);
  117.     }   
  118.     if (observers) 
  119.     CleanupObservers(observers);
  120. }
  121.  
  122. void Text::Init()
  123. {
  124.     marks= 0;
  125.     tabWidth= cTabw;
  126.     observers= 0;
  127.     paraStyle= new_ParaStyle();
  128.     charStyle= gCharStyles->Default();
  129. }
  130.  
  131. void Text::InitNew()
  132. {
  133.     Init();
  134. }
  135.  
  136. int Text::GrowSize(int minSize)
  137. {
  138.     if (cMaxInt - minSize > minSize)
  139.     return minSize+minSize;
  140.     int d= minSize-Size();
  141.     int m= Math::Min(2000, d);
  142.     if (cMaxInt - Size() > m)
  143.     return Size()+m;
  144.     Error("GrowSize", "Cannot grow text");
  145.     return 0;
  146. }
  147.  
  148. void Text::ReplaceRange(int, int, Text *, int, int)
  149. {
  150.     AbstractMethod("ReplaceRange");
  151. }
  152.  
  153. void Text::Cut(int from,int to)
  154. {
  155.     if (marks)
  156.     marks->Replace(from, to, 0);
  157.     Text *nullText= MakeScratchText(0, 0);
  158.     ReplaceRange(from, to, nullText, 0, 0);
  159.     SafeDelete(nullText);
  160.     Send(cIdNone, eTextDeleted, changeRec(from, to));     
  161. }
  162.  
  163. void Text::Paste(Text *src, int from, int to)
  164. {
  165.     if (marks) 
  166.     marks->Replace(from, to, src->End());
  167.     
  168.     ReplaceRange(from, to, src, 0, src->End());
  169.     Send(cIdNone, eTextReplaced, changeRec(from, to, src->End()));     
  170. }
  171.  
  172. void Text::Copy(Text *dst, int from, int to)
  173. {
  174.     dst->ReplaceRange(0, dst->End(), this, from, to);
  175. }
  176.  
  177. void Text::CopyInStr(byte*, int, int, int)
  178. {
  179.     AbstractMethod("CopyInStr");
  180. }
  181.  
  182. void Text::Insert(byte c, int from, int to)
  183. {
  184.     Text *t= MakeScratchText(&c, 1);
  185.     Paste(t, from, to);
  186.     SafeDelete(t);
  187. }
  188.  
  189. void Text::InsertStr(int from, int to, byte *str, int len)
  190. {
  191.     if (len == -1 && str)
  192.     len= strlen((char*)str);
  193.     Text *t= MakeScratchText(str, len);
  194.     Paste(t, from, to);
  195.     SafeDelete(t);
  196. }
  197.  
  198. void Text::ReplaceWithStr(byte *buf, int len)
  199. {
  200.     InsertStr(0, End(), buf, len);
  201. }
  202.  
  203. void Text::SetFStringVL(char *fmt, va_list va)
  204. {
  205.     byte *buf= (byte*)strvprintf(fmt, va);
  206.     ReplaceWithStr(buf, -1);
  207.     SafeDelete(buf);
  208. }
  209.  
  210. void Text::SetFString(char *va_(fmt), ...)
  211. {
  212.     va_list ap;
  213.     va_start(ap,va_(fmt));
  214.     SetFStringVL(va_(fmt), ap);
  215.     va_end(ap);    
  216. }
  217.  
  218. int Text::Search(
  219.     RegularExp *rex, int *nMatched, int start, int range, bool dir
  220. )
  221. {
  222.     int pos;
  223.     char *s= AsString();
  224.     if (dir == cSearchForward) 
  225.     pos= rex->SearchForward (s, nMatched, start, Size(), range, 0);
  226.     else
  227.     pos= rex->SearchBackward (s, nMatched, start, Size(), range, 0); 
  228.     delete s;
  229.     return pos;
  230. }
  231.  
  232. bool Text::IsParaStart(int at)
  233. {
  234.     return (at <= 0) || IsPara((*this)[at-1]);
  235. }
  236.  
  237. bool Text::IsParaEnd(int at)
  238. {
  239.     return (at >= Size()) || IsPara((*this)[at]);
  240. }
  241.  
  242. Text *Text::MakeScratchText(byte *, int) 
  243. {
  244.     AbstractMethod("MakeScratchText");
  245.     return 0;
  246. }
  247.  
  248. Text* Text::Save(int from, int to)
  249. {
  250.     if (!CheckRange(Size(), from, to))
  251.     Error("Save", "Out of range from= %d to=%d size= %d", from, to, Size());
  252.     Text *t= (Text*)this->New();
  253.     Copy(t, from, to);
  254.     return t;
  255. }
  256.  
  257. void Text::Append(byte c)
  258. {
  259.     int at= Math::Max(0, End());
  260.     Insert(c, at, at);
  261. }
  262.  
  263. byte& Text::operator[](int )
  264. {
  265.     static byte dummyc= '\0';
  266.     AbstractMethod("operator[]");
  267.     return dummyc;
  268. }
  269.  
  270. void Text::Empty()                                         
  271. {
  272.     Cut(0, End());
  273. }
  274.  
  275. int Text::Size()                                         
  276. {
  277.     AbstractMethod("Size");
  278.     return 0;
  279. }
  280.  
  281. void Text::GetWordRange(int at, int *start, int *end)
  282. {
  283.     register int i;
  284.  
  285.     if (!CheckRange(Size(), at, at))
  286.     return;
  287.  
  288.     for (i= at-1; i >= 0 && Isinword((*this)[i]); i--)
  289.     ;
  290.     *start= i+1; 
  291.     for (i= at; i < Size() && Isinword((*this)[i]); i++)
  292.     ; 
  293.     *end= i;
  294. }
  295.  
  296. void Text::GetParaRange(int at, int *start, int *end)
  297. {
  298.     register int i, ch;
  299.  
  300.     if (!CheckRange(Size(), at, at))
  301.     return;
  302.  
  303.     for (i= at-1; i >= 0; i--) {
  304.     ch= (*this)[i];
  305.     if (IsPara(ch))
  306.         break;
  307.     }
  308.     *start= i+1; 
  309.     for (i= at; i < Size(); i++) {
  310.     ch= (*this)[i];
  311.     if (IsPara(ch))
  312.         break; 
  313.     }
  314.     *end= Math::Min(Size(), i+1);
  315. }
  316.  
  317. int Text::FindLastBreak(int from)
  318. {
  319.     for (int i= from-1; i >= 0; i--)
  320.     if (IsBreak((*this)[i]))
  321.         break;
  322.     return i;
  323. }
  324.  
  325. int Text::FindNextBreak(int from)
  326. {
  327.     for (int i= from; i < Size(); i++)
  328.     if (IsBreak((*this)[i]))
  329.         break;
  330.     return i;
  331. }
  332.  
  333. void Text::SetDefTab(int t)
  334. {
  335.     tabWidth= t;
  336. }
  337.  
  338. int Text::GetDefTab()
  339. {
  340.     return tabWidth;
  341. }
  342.  
  343. TextIter *Text::MakeIterator(int,int)
  344. {
  345.     AbstractMethod("MakeIterator ");
  346.     return 0;    
  347. }
  348.  
  349. //---- style access
  350.  
  351. void Text::SetCharStyle(TxtCharProp what, int, int, const CharStyleSpec &st)
  352. {
  353.     charStyle= gCharStyles->ChangeProperty(charStyle, what, st);    
  354.     Send(cIdNone, eTextChangedRange, changeRec(0, Size()));     
  355. }
  356.  
  357. void Text::SetParaStyle(TxtParaProp what, int, int, const ParaDesc &pd)
  358. {
  359.     paraStyle= gParaStyles->ChangeProperty(paraStyle, what, pd);
  360.     Send(cIdNone, eTextChangedRange, changeRec(0, Size()));     
  361. }
  362.  
  363. CharStyle *Text::GetCharStyle(int)
  364. {
  365.     return charStyle;
  366. }
  367.  
  368. CharStyle *Text::GetCurrentCharStyle()
  369. {
  370.     return 0;
  371. }
  372.  
  373. ParaStyle *Text::GetParaStyle(int)
  374. {
  375.     return paraStyle;
  376. }
  377.  
  378. void Text::SetFont(Font *fd, int from, int to)
  379. {
  380.     SetCharStyle(eTxtCPFontAll, from, to, CharStyleSpec(fd));
  381. }
  382.  
  383. Font *Text::GetFont(int)
  384. {
  385.     return charStyle->GetFont();
  386. }
  387.  
  388. void Text::ResetCurrentCharStyle()
  389. {
  390. }
  391.  
  392. //---- TextPainter contract
  393.  
  394. int Text::GetNextFontChange(int, CharStyle *&sp)
  395. {
  396.     sp= charStyle;
  397.     return cMaxInt;
  398. }
  399.  
  400. byte Text::GetMarkChar()
  401. {
  402.     return 0;
  403. }
  404.  
  405. VisualMark *Text::GetVisualMarkAt(int)
  406. {
  407.     return 0;
  408. }
  409.  
  410. bool Text::IsVisualMark(int)
  411. {
  412.     return FALSE;
  413. }
  414.  
  415. byte *Text::GetLineAccess(byte**, int, int)
  416. {
  417.     AbstractMethod("GetLine");
  418.     return 0;
  419. }
  420.  
  421. //---- conversion
  422.  
  423. char *Text::AsString()
  424. {
  425.     int s= Size();
  426.     char *buf= new char[s];
  427.     CopyInStr((byte*)buf, s, 0, s);
  428.     return buf;    
  429. }
  430.  
  431. OStream& Text::PrintOn(OStream &s)
  432. {
  433.     Object::PrintOn(s);
  434.     return s << charStyle SP << paraStyle SP;
  435. }
  436.  
  437. IStream& Text::ReadFrom(IStream &s)
  438. {
  439.     Object::ReadFrom(s);
  440.     return s >> charStyle >> paraStyle;
  441. }
  442.  
  443. OStream& Text::PrintOnAsPureText(OStream &s)
  444. {
  445.     AbstractMethod("PrintOnAsPureText");
  446.     return s;
  447. }
  448.  
  449. IStream& Text::ReadFromAsPureText(IStream &s, long)
  450. {
  451.     AbstractMethod("ReadFromAsPureText");
  452.     return s;
  453. }
  454.  
  455. bool Text::IsEmpty() 
  456. {
  457.     return End() == 0;
  458. }
  459.  
  460. void Text::AddMark(Mark *m)
  461. {
  462.     if (marks == 0)
  463.     marks= new MarkList;
  464.     marks->Add(m);
  465. }
  466.  
  467. Mark *Text::RemoveMark(Mark *m)
  468. {
  469.     if (marks == 0)
  470.     marks= new MarkList;
  471.     return marks->Remove(m);
  472. }
  473.  
  474. Iterator *Text::GetMarkIter()
  475. {
  476.     if (marks == 0)
  477.     marks= new MarkList;
  478.     return marks->MakeIterator();
  479. }
  480.  
  481. MarkList *Text::GetMarkList()
  482. {
  483.     if (marks == 0)
  484.     marks= new MarkList;
  485.     return marks;
  486. }
  487.  
  488. void Text::InspectorId(char *b, int s)
  489. {
  490.     for (int i= 0; i < Math::Min(s-1, Size()-1); i++)
  491.     b[i]= (*this)[i];
  492.     b[i]= '\0';
  493. }
  494.  
  495. bool Text::IsEqual(Object *text)                                         
  496. {
  497.     if (text == 0 || ! text->IsKindOf(Text))
  498.     return FALSE;
  499.     byte *p1= (byte*)AsString();
  500.     byte *p2= (byte*)text->AsString();
  501.     int equal=  StrCmp(p1, p2, -1, sortmap) == 0;
  502.     SafeDelete(p1);
  503.     SafeDelete(p2);
  504.     return equal;
  505. }
  506.  
  507. u_long Text::Hash()                                         
  508. {
  509.     u_long hash;
  510.     byte *p= (byte*)AsString();
  511.     hash= strhash(p);
  512.     return hash;
  513. }
  514.  
  515. //---- observing ----------------------------------------------------------
  516.     
  517. Collection *Text::MakeObserverColl()
  518. {
  519.     return observers= new OrdCollection(4);
  520. }
  521.  
  522. Collection *Text::GetObservers()
  523. {    
  524.     return observers;
  525. }
  526.  
  527. void Text::DestroyObserverColl()
  528. {
  529.     SafeDelete(observers);
  530. }
  531.  
  532. void Text::SetObserverColl(Collection *cp)
  533. {
  534.     SafeDelete(observers);
  535.     observers= cp;
  536. }
  537.  
  538. //----- class TextIter ----------------------------------------------------
  539.  
  540. TextIter::TextIter(Text *s,int from,int to)
  541.     ct= s; 
  542.     ce= Math::Max(from,0); 
  543.     upto= Math::Min(to,s->Size());
  544. }
  545.  
  546. TextIter::~TextIter()
  547. }
  548.  
  549. void TextIter::Reset(Text *s,int from,int to)
  550.     ct= s; 
  551.     ce= Math::Max(from,0); 
  552.     upto= Math::Min(to,s->Size());
  553. }
  554.  
  555. int TextIter::operator()(int *, LineDesc*)  
  556. {
  557.     return cEOT;
  558. }
  559.  
  560. int TextIter::GetPos()  
  561. {
  562.     return ce;
  563. }
  564.  
  565. Font *TextIter::FontAt(int)
  566.     return ct->GetFont(); 
  567.  
  568. int TextIter::Unget()
  569. {
  570.     return ce= unget;
  571. }
  572.  
  573. int TextIter::Token(int*, LineDesc*)  
  574. {
  575.     return cEOT;
  576. }
  577.  
  578. int TextIter::GetLastPos()                 // get last position
  579.     return unget; 
  580. }
  581.  
  582. void TextIter::SetPos(int newPos)
  583.     ce= newPos; 
  584. }
  585.  
  586. AutoTextIter::AutoTextIter(Text *t, int from, int to)
  587.     ti= t->MakeIterator(from, to);
  588. }
  589.  
  590.